#ifndef __SERIAL
#define __SERIAL

#include "config.h"

typedef struct _Serial Serial;
#define SERIAL(any) ((Serial *)(any))
typedef enum _SerialType SerialType;
#ifndef __OBJ_HANDLER__
        #define __OBJ_HANDLER__
typedef void (*ObjectIRQHandler)(void *object);
#endif

/**
 * @brief 串口接收中断的父类处理钩子，请注意，务必先检测 flag 是否为 1（0 为
 * 错误）
 */
typedef void (*SerialIRQHandler)(void *object, uint8_t *datas);
#define SERIAL_IRQ_HANDLER(any) ((void (*)(void *, uint8_t *))(any))

struct _Serial
{
        USART_TypeDef   *usart;
        SerialIRQHandler handler;
        uint32_t         RCC_APB2Periph;
        uint8_t          NVIC_IRQChannel;
        uint8_t          flag;
};

enum _SerialType
{
        SERIAL_TYPE_USART1,
        SERIAL_TYPE_USART2,
        SERIAL_TYPE_USART3,
};

/**
 * @brief 串口对象初始化
 * @param s_type 串口号，类型为 SerialType
 * @param handler 处理串口接收数据的父类钩子。不能为空！
 */
extern void
serial_init(Serial *self, SerialType s_type, SerialIRQHandler handler);

/**
 * @brief 串口发送 raw text 文本，末尾包含 "\r\n" 则代表结束
 * @param buf 发送内容的缓冲区，末尾必须为 '\0'
 */
extern void serial_send_text(const Serial *self, const uint8_t *buf);

/**
 * @brief 串口发送一个 '\0'
 */
extern void serial_send_byte0(const Serial *self);

#endif
